using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.ComponentModel.Design.Serialization;
using System.CodeDom;

namespace GuavaData
{
    [DesignerSerializer(typeof(GComponentBaseSerializer),
    typeof(CodeDomSerializer))]
    public abstract partial class GComponentBase : Component, Guava
    {
        public GComponentBase()
        {
            InitializeComponent();
        }

        public GComponentBase(IContainer container)
        {
            container.Add(this);

            InitializeComponent();
        }

        #region Guava Members

        public abstract LaunchType LType { get; }
        public abstract ControlType CType { get; }
        public abstract string GText { get; }
        public abstract string GName { get; set; }
        [Browsable(false)]
        public System.Drawing.Point GLocation
        {
            get { return new System.Drawing.Point(); }
        }
        [Browsable(false)]
        public System.Drawing.Size GSize
        {
            get { return new System.Drawing.Size(); }
        }
        public abstract List<Guava> GComponents { get; }
        public abstract void GBind(string table, int i);
        [Browsable(false)]
        public string GDefault
        {
            get { return null; }
        }
        [Browsable(false)]
        public string GToolTip
        {
            get { return null; }
        }
        public abstract GuavaData.Domain.Domain GDomain { get; }
        public Guava this[string s]
        {
            get
            {
                foreach (Guava g in this.GComponents) if (g.GName == s) return g;
                return null;
            }
        }

        #endregion

        public virtual void AttachComponent(GuavaForm gf)
        {
            gf.AddGComponent(this);
        }
    }

    public class GComponentBaseSerializer : CodeDomSerializer
    {
        public override object Serialize(
        IDesignerSerializationManager manager,
        object value)
        {
            CodeDomSerializer baseSerializer =
            (CodeDomSerializer)manager.GetSerializer(
            typeof(Component),
            typeof(CodeDomSerializer));

            object codeObject = baseSerializer.Serialize(manager, value);

            if (codeObject is CodeStatementCollection)
            {
                CodeStatementCollection statements =
                    (CodeStatementCollection)codeObject;

                // call a custom method.
                //
                CodeExpression targetObject =
                   base.SerializeToExpression(manager, value);
                if (targetObject != null)
                {
                    CodeMethodInvokeExpression methodCall =
                        new CodeMethodInvokeExpression(targetObject, "AttachComponent");

                    methodCall.Parameters.Add(new CodeThisReferenceExpression());

                    statements.Add(methodCall);
                }
            }
            // finally, return the statements that have been created
            return codeObject;
        }
    }
}
